/*=============================================================

PROGRAMMING TECHNIQUES FOR SUPERCOMPUTERS

Assignment Number 1

Task 3

=============================================================*/

#include <stdio.h>
#include "timing.hh"
#include <iostream>
#include <math.h>
#include <fstream>

int main(int argc, char *argv[]) 
{
	double wcTimeStart,wcTimeEnd,cpuTimeStart,cpuTimeEnd,wcTime, cpTime;	
	std::ofstream fileoutd("plot3.dat");
	fileoutd << "# Plot for Task 3" << std::endl;
	fileoutd << "# OFS\t MFLOP/sec" << std::endl;

	int N=1024;
	double *a = new double[N]; 
	for (int i = 0; i<N; ++i)
	{
		a[i] = i*1.0;
	}
		
	long  repeat =1;
	const double s=2.;
	std::cout << "Please enter the increment of the OFS desired\n (Increment of 1 will require longer runtime)" << std::endl;
	unsigned k;
	std::cin >> k;
	std::cout<< "Running Task 3 with OFS increment of " << k <<  std::endl;
	std::cout << "OFS" << "\t" << "MFLOP/sec" << std::endl;
	
	for (int OFS =1; OFS<1024; OFS= OFS+k)
	{
		double runtime =0.;
		for (; runtime <0.1; repeat*=2)
		{	
			timing(wcTimeStart,cpuTimeStart);
			for (int r=0; r<repeat; ++r)
			{
				#pragma nounroll
				for (int i = OFS; i<N; ++i)
				{
					a[i] = s*a[i-OFS];
				}
				if (a[N-1] <0.) std::cout << "Dummy Loop Encountered"<< std::endl;
			}
			timing(wcTimeEnd,cpuTimeEnd);	
			runtime=wcTimeEnd-wcTimeStart;				
	}


	repeat/=2;
	long noFlops = (N-OFS)*1*repeat;
	double mFlops = noFlops/runtime/1000000;
	std::cout << OFS <<"\t" << mFlops << std::endl;
	fileoutd << OFS <<"\t" << mFlops << std::endl;
	}
	std::cout<< "Finished Task 3. \nRun gnuplot with 'plot3.dat' " << std::endl;
	fileoutd.close();
	delete [] a;
	return 0;
}
